home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / player.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  10.5 KB  |  446 lines

  1. /* player.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: player.c,v 4.0 1994/01/11 17:51:40 espie Exp espie $
  6.  * $Log: player.c,v $
  7.  * Revision 4.0  1994/01/11  17:51:40  espie
  8.  * Use the new UI calls.
  9.  * Use the new pref settings.
  10.  *
  11.  * Revision 1.14  1994/01/09  23:24:37  Espie
  12.  * Last bug fix.
  13.  *
  14.  * Revision 1.13  1994/01/09  17:36:22  Espie
  15.  * Generalized open.c.
  16.  *
  17.  * Revision 1.12  1994/01/08  03:55:43  Espie
  18.  * Suppressed really outdated code.
  19.  * New names: new_channel_tag_list, release_audio_channel.
  20.  *
  21.  * Revision 1.11  1994/01/08  02:04:21  Espie
  22.  * Some notice to status.
  23.  *
  24.  * Revision 1.10  1994/01/07  15:06:26  Espie
  25.  * *** empty log message ***
  26.  *
  27.  * Revision 1.9  1994/01/06  22:32:42  Espie
  28.  * Use new pref scheme.
  29.  *
  30.  * Revision 1.8  1994/01/05  16:10:49  Espie
  31.  * *** empty log message ***
  32.  *
  33.  * Revision 1.7  1994/01/05  14:54:09  Espie
  34.  * *** empty log message ***
  35.  *
  36.  * Revision 1.6  1994/01/05  13:50:43  Espie
  37.  * Use get_ui
  38.  *
  39.  * Revision 1.5  1994/01/05  01:59:14  Espie
  40.  * Added prototypes.
  41.  *
  42.  * Revision 1.4  1993/12/28  13:54:44  Espie
  43.  * Use autoinit feature of display.c
  44.  *
  45.  * Revision 1.3  1993/12/27  02:35:02  Espie
  46.  * discard_buffer forgotten...
  47.  *
  48.  * Revision 1.2  1993/12/26  18:54:21  Espie
  49.  * Handle errors better.
  50.  *
  51.  * Revision 1.1  1993/12/26  00:55:53  Espie
  52.  * Initial revision
  53.  *
  54.  * Revision 3.18  1993/12/04  16:12:50  espie
  55.  * Lots of changes.
  56.  *
  57.  * Revision 3.17  1993/11/19  14:27:06  espie
  58.  * Stupid bug.
  59.  *
  60.  * Revision 3.16  1993/11/17  15:31:16  espie
  61.  * New high-level functions.
  62.  *
  63.  * Revision 3.15  1993/11/11  20:00:03  espie
  64.  * Amiga support.
  65.  *
  66.  * Revision 3.14  1993/08/04  11:34:33  espie
  67.  * *** empty log message ***
  68.  *
  69.  * Revision 3.13  1993/07/18  11:49:29  espie
  70.  * Bug with delay_pattern: can't factorize the check for effect thingy.
  71.  *
  72.  * Revision 3.12  1993/07/18  10:39:44  espie
  73.  * Added forking under unix.
  74.  *
  75.  *
  76.  * Revision 3.10  1993/05/09  14:06:03  espie
  77.  * Reniced verbose output display.
  78.  *
  79.  * Revision 3.9  1993/04/25  14:08:15  espie
  80.  * Bug fix: now use correct finetune when loading samples/starting notes.
  81.  *
  82.  * Revision 3.8  1993/01/15  14:00:28  espie
  83.  * Added bg/fg test.
  84.  *
  85.  * Revision 3.6  1992/11/27  10:29:00  espie
  86.  * General cleanup
  87.  *
  88.  * Revision 3.5  1992/11/24  10:51:19  espie
  89.  * un#ifdef'ed showseq code.
  90.  *
  91.  * Revision 3.3  1992/11/22  17:20:01  espie
  92.  * Added <> operators.
  93.  * Added update frequency on the fly.
  94.  *
  95.  * Revision 3.2  1992/11/20  14:53:32  espie
  96.  * Added finetune.
  97.  *
  98.  * Revision 3.1  1992/11/19  20:44:47  espie
  99.  * Protracker commands.
  100.  *
  101.  * Revision 3.0  1992/11/18  16:08:05  espie
  102.  * New release.
  103.  *
  104.  * Revision 2.19  1992/11/17  17:15:37  espie
  105.  * Added interface using may_getchar(). Still primitive, though.
  106.  * imask, start.
  107.  * Added transpose feature.
  108.  * Added possibility to get back to MONO for the sgi.
  109.  * Added stereo capabilities to the indigo version.
  110.  * Added two level of fault tolerancy.
  111.  * Added some control on the number of replays,
  112.  * and better error recovery.
  113.  */
  114.      
  115. #include <stdio.h>
  116.      
  117. #include "defs.h"
  118. #include "song.h"
  119. #include "channel.h"
  120. #include "extern.h"
  121. #include "tags.h"
  122. #include "prefs.h"
  123.      
  124.  
  125. ID("$Id: player.c,v 4.0 1994/01/11 17:51:40 espie Exp espie $")
  126.      
  127.  
  128. /* setting up a given note */
  129.  
  130. void reset_note(ch, note, pitch)
  131. struct channel *ch;
  132. int note;
  133. int pitch;
  134.    {
  135.    ch->pitch = pitch;
  136.    ch->note = note;
  137.    ch->viboffset = 0;
  138.    play_note(ch->audio, ch->samp, pitch);
  139.    }
  140.  
  141. /* changing the current pitch (value
  142.  * may be temporary, and not stored
  143.  * in channel pitch, for instance vibratos.
  144.  */
  145. void set_current_pitch(ch, pitch)
  146. struct channel *ch;
  147. int pitch;
  148.    {
  149.       /* save current pitch in case we want to change
  150.        * the step table on the run
  151.    ch->cpitch = pitch;
  152.    ch->step = step_table[pitch];
  153.       */
  154.    set_play_pitch(ch->audio, pitch);
  155.    }
  156.  
  157. /* changing the current volume. You HAVE to get through
  158.  * there so that it will work on EVERY machine.
  159.  */
  160. void set_current_volume(ch, volume)
  161. struct channel *ch;
  162. int volume;
  163.    {
  164.    ch->volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  165.    set_play_volume(ch->audio, ch->volume);
  166.    }
  167.  
  168. void set_position(ch, pos)
  169. struct channel *ch;
  170. int pos;
  171.    {
  172.    set_play_position(ch->audio, pos);
  173.    }
  174.  
  175. /* init_channel(ch, dummy):
  176.  * setup channel, with initially
  177.  * a dummy sample ready to play,
  178.  * and no note.
  179.  */
  180. LOCAL void init_channel(ch)
  181. struct channel *ch;
  182.    {
  183.    ch->samp = NULL;
  184.    ch->finetune = 0;
  185.    ch->audio = new_channel_tag_list(TAG_END);
  186.    ch->volume = 0; 
  187.    ch->pitch = 0; 
  188.    ch->note = NO_NOTE;
  189.  
  190.       /* we don't setup arpeggio values. */
  191.    ch->viboffset = 0; 
  192.    ch->vibdepth = 0;
  193.  
  194.    ch->slide = 0; 
  195.  
  196.    ch->pitchgoal = 0; 
  197.    ch->pitchrate = 0;
  198.  
  199.    ch->volumerate = 0;
  200.  
  201.    ch->vibrate = 0;
  202.    ch->adjust = do_nothing;
  203.    }
  204.  
  205.  
  206.  
  207. LOCAL int VSYNC;          /* base number of sample to output */
  208. LOCAL void (*eval[NUMBER_EFFECTS]) P((struct automaton *a, struct channel *ch));
  209.                     /* the effect table */
  210. LOCAL int oversample;     /* oversample value */
  211. LOCAL int frequency;      /* output frequency */
  212. LOCAL int channel;        /* channel loop counter */
  213.  
  214. LOCAL struct channel chan[NUMBER_TRACKS];
  215.                     /* every channel */
  216.  
  217. LOCAL struct sample_info *voices;
  218.  
  219. LOCAL struct automaton a;
  220.  
  221.  
  222. void init_player(o, f)
  223. int o, f;
  224.    {
  225.    oversample = o;
  226.    frequency = f;
  227.    init_tables(o, f);
  228.    init_effects(eval);
  229.    }
  230.  
  231. LOCAL void setup_effect(ch, a, e)
  232. struct channel *ch;
  233. struct automaton *a;
  234. struct event *e;
  235.    {
  236.    int samp, cmd;
  237.  
  238.       /* retrieves all the parameters */
  239.    samp = e->sample_number;
  240.  
  241.       /* load new instrument */
  242.    if (samp)  
  243.       {
  244.          /* note that we can change sample in the middle
  245.           * of a note. This is a *feature*, not a bug (see
  246.           * made). Precisely: the sample change will be taken
  247.           * into account for the next note, BUT the volume change
  248.           * takes effect immediately.
  249.           */
  250.       ch->samp = voices + samp;
  251.       ch->finetune = voices[samp].finetune;
  252.       if ((1L<<samp) & get_pref_scalar(PREF_IMASK))
  253.          ch->samp = voices;
  254.       set_current_volume(ch, voices[samp].volume);
  255.       }
  256.  
  257.    a->note = e->note;
  258.    if (a->note != NO_NOTE)
  259.       a->pitch = pitch_table[a->note][ch->finetune];
  260.    else
  261.       a->pitch = e->pitch;
  262.    cmd = e->effect;
  263.    a->para = e->parameters;
  264.  
  265.    if (a->pitch >= REAL_MAX_PITCH)
  266.       {
  267.       char buffer[60];
  268.       sprintf(buffer,"Pitch out of bounds %d", a->pitch);
  269.       status(buffer);
  270.       a->pitch = 0;
  271.       error = FAULT;
  272.       }
  273.  
  274.    dump_event(ch, e);
  275.  
  276.       /* check for a new note: portamento
  277.        * is the special case where we do not restart
  278.        * the note.
  279.        */
  280.    if (a->pitch && cmd != EFF_PORTA && cmd != EFF_PORTASLIDE)
  281.       reset_note(ch, a->note, a->pitch);
  282.    ch->adjust = do_nothing;
  283.       /* do effects */
  284.    (eval[cmd])(a, ch);
  285.    }
  286.  
  287.  
  288. LOCAL void adjust_sync(ofreq, tempo)
  289. int ofreq, tempo;
  290.    {
  291.    VSYNC = ofreq * NORMAL_FINESPEED / tempo;
  292.    }
  293.  
  294. LOCAL void play_once(a)
  295. struct automaton *a;
  296.    {
  297.    int channel;
  298.  
  299.    if (a->do_stuff & DELAY_PATTERN)
  300.       for (channel = 0; channel < NUMBER_TRACKS; channel++)
  301.          /* do the effects */
  302.          (chan[channel].adjust)(chan + channel);
  303.    else
  304.       {  
  305.       if (a->counter == 0)
  306.          {
  307.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  308.             /* setup effects */
  309.             setup_effect(chan + channel, a, 
  310.                &(a->pattern->e[channel][a->note_num]));
  311.          dump_event(0, 0);
  312.          }
  313.       else
  314.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  315.             /* do the effects */
  316.             (chan[channel].adjust)(chan + channel);
  317.       }
  318.  
  319.       /* advance player for the next tick */
  320.    next_tick(a);
  321.       /* actually output samples */
  322.    resample(oversample, VSYNC / a->finespeed);
  323.    }
  324.  
  325. LOCAL struct tag pres[2];
  326.  
  327.  
  328. struct tag *play_song(song, start)
  329. struct song *song;
  330. int start;
  331.    {
  332.    int tempo;
  333.    int countdown;      /* keep playing the tune or not */
  334.  
  335.    song_title(song->title);
  336.    pres[1].type = TAG_END;
  337.    
  338.    tempo = get_pref_scalar(PREF_SPEED);
  339.  
  340.    adjust_sync(frequency, tempo);
  341.     /* a repeats of 0 is infinite replays */
  342.    
  343.    countdown = get_pref_scalar(PREF_REPEATS);
  344.    if (countdown == 0)
  345.       countdown = 50000;   /* ridiculously huge number */
  346.  
  347.    voices = song->samples; 
  348.  
  349.    init_automaton(&a, song, start);
  350.  
  351.    release_audio_channels();
  352.  
  353.    for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  354.       init_channel(chan + channel);
  355.  
  356.    while(countdown)
  357.       {
  358.       struct tag *result;
  359.       
  360.       play_once(&a);
  361.       result = get_ui();
  362.       while(result = get_tag(result))
  363.          {
  364.          switch(result->type)
  365.             {  
  366.          case UI_LOAD_SONG:
  367.             if (!result->data.pointer)
  368.                break;
  369.          case UI_NEXT_SONG:
  370.          case UI_PREVIOUS_SONG:
  371.             discard_buffer();
  372.             pres[0].type = result->type;
  373.             pres[0].data = result->data;
  374.             return pres;
  375.          case UI_QUIT:
  376.             discard_buffer();
  377.             end_all(0);
  378.             /* NOTREACHED */
  379.          case UI_SET_BPM:
  380.             tempo = result->data.scalar;
  381.             adjust_sync(frequency, tempo);
  382.             break;
  383.          case UI_RESTART:
  384.             discard_buffer();
  385.             init_automaton(&a, song, start);
  386.             release_audio_channels();
  387.             for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  388.                init_channel(chan + channel);
  389.             break;
  390.          case UI_JUMP_TO_PATTERN:
  391.             if (result->data.scalar >= 0 && result->data.scalar < a.info->length)
  392.                {
  393.                discard_buffer();
  394.                init_automaton(&a, song, result->data.scalar);
  395.                }
  396.             break;
  397.             /*
  398.          case ' ':
  399.             while (may_getchar() == EOF)
  400.                ;
  401.             break;
  402.              */
  403.          default:
  404.             break;
  405.             }
  406.          result++;
  407.          }
  408.  
  409.       {
  410.       int new_freq;
  411.       if (new_freq = update_frequency())
  412.          {
  413.          frequency = new_freq;
  414.          adjust_sync(frequency, tempo);
  415.          init_tables(oversample, frequency);
  416.          }
  417.       }
  418.  
  419.       switch(error)
  420.          {
  421.       case NONE:
  422.          break;
  423.       case ENDED:
  424.          countdown--;
  425.          break;
  426.       case SAMPLE_FAULT:
  427.       case FAULT:
  428.       case PREVIOUS_SONG:
  429.       case NEXT_SONG:
  430.       case UNRECOVERABLE:
  431.          if ( (error == SAMPLE_FAULT && get_pref_scalar(PREF_TOLERATE))
  432.             ||(error == FAULT && get_pref_scalar(PREF_TOLERATE) > 1) )
  433.             break;
  434.          pres[0].type = PLAY_ERROR;
  435.          pres[0].data.scalar = error;
  436.          return pres;
  437.       default:
  438.          break;
  439.          }
  440.          error = NONE;
  441.       }
  442.    pres[0].type = TAG_IGNORE;      
  443.    return pres;
  444.    }
  445.  
  446.